"""
分割控制组件
"""

import tkinter as tk
from tkinter import filedialog, messagebox
import threading
import numpy as np
from pathlib import Path
from typing import TYPE_CHECKING

from ...utils import FileUtils

if TYPE_CHECKING:
    from ..main_window import MainWindow


class SegmentationControllerMixin:
    """分割控制 Mixin 类"""
    
    def segment_auto(self: 'MainWindow'):
        """自动分割"""
        if not self._check_prerequisites():
            return
        
        mode_info = "（景深图输入）" if self.use_depth_input else ""
        self.update_status(f"正在分割图片{mode_info}...")
        self.progress.pack(side=tk.BOTTOM, fill=tk.X, before=self.status_bar)
        self.progress.start()
        
        def segment_thread():
            # 第一步：rembg预处理（如果开启）
            if self.use_rembg:
                self.logger.info("应用rembg背景移除...")
                processed_image = self.bg_remover.remove_background(self.image)
                if processed_image is not None:
                    # 转换RGBA为RGB（白色背景）
                    base_image = self.bg_remover.get_rgb_from_rgba(processed_image)
                    self.logger.info("rembg预处理完成")
                else:
                    self.logger.warning("rembg处理失败，使用原图")
                    base_image = self.image
            else:
                base_image = self.image
            
            # 第二步：根据开关决定SAM的输入图片
            if self.use_depth_input and self.depth_map is not None:
                # 使用景深图作为输入
                colored_depth = self.depth_processor.get_depth_visualization()
                if colored_depth is None:
                    colored_depth = np.stack([self.depth_map] * 3, axis=-1)
                sam_input_image = colored_depth
                self.logger.info("自动分割：使用景深图作为SAM输入")
            else:
                # 使用处理后的图片作为输入
                sam_input_image = base_image
                self.logger.info("自动分割：使用原图作为SAM输入")
            
            results = self.sam_model.segment_auto(sam_input_image)
            self.root.after(0, lambda: self.on_segment_completed(results))
        
        threading.Thread(target=segment_thread, daemon=True).start()
    
    def on_segment_completed(self: 'MainWindow', results):
        """分割完成回调"""
        self.progress.stop()
        self.progress.pack_forget()
        
        if not results:
            self.update_status("分割失败或未检测到对象")
            messagebox.showwarning("提示", "未检测到对象！", parent=self.root)
            return
        
        self.all_results = results
        
        # 可视化结果
        result_image = self.image_processor.visualize_masks(self.image, results)
        self.current_result_image = result_image  # 保存结果图片用于窗口调整
        self.display_image(result_image, self.result_canvas)
        
        self.update_status(f"分割完成，共检测到 {len(results)} 个对象")
        messagebox.showinfo("成功", f"分割完成！\n共检测到 {len(results)} 个对象。", parent=self.root)
    
    def segment_interactive(self: 'MainWindow'):
        """交互式分割"""
        if not self._check_prerequisites():
            return
        
        mode_info = "（景深图输入）" if self.use_depth_input else ""
        self.update_status(f"正在分割选中区域{mode_info}...")
        self.progress.pack(side=tk.BOTTOM, fill=tk.X, before=self.status_bar)
        self.progress.start()
        
        def segment_thread():
            # 准备提示
            point_coords = None
            point_labels = None
            box = None
            
            if self.selected_points:
                point_coords = np.array(self.selected_points)
                point_labels = np.array(self.selected_labels)
            
            if self.selected_box:
                box = np.array(self.selected_box)
            
            # 第一步：rembg预处理（如果开启）
            if self.use_rembg:
                self.logger.info("应用rembg背景移除...")
                processed_image = self.bg_remover.remove_background(self.image)
                if processed_image is not None:
                    # 转换RGBA为RGB（白色背景）
                    base_image = self.bg_remover.get_rgb_from_rgba(processed_image)
                    self.logger.info("rembg预处理完成")
                else:
                    self.logger.warning("rembg处理失败，使用原图")
                    base_image = self.image
            else:
                base_image = self.image
            
            # 第二步：根据开关决定SAM的输入图片
            if self.use_depth_input and self.depth_map is not None:
                # 使用景深图作为输入（3通道RGB格式）
                colored_depth = self.depth_processor.get_depth_visualization()
                if colored_depth is None:
                    # 如果可视化失败，将灰度图转为3通道
                    colored_depth = np.stack([self.depth_map] * 3, axis=-1)
                
                sam_input_image = colored_depth
                self.logger.info("使用景深图作为SAM输入")
            else:
                # 使用处理后的图片作为输入
                sam_input_image = base_image
                self.logger.info("使用原图作为SAM输入")
            
            # 执行分割
            result = self.sam_model.segment_interactive(
                sam_input_image,
                point_coords=point_coords,
                point_labels=point_labels,
                box=box
            )
            
            self.root.after(0, lambda: self.on_interactive_segment_completed(result))
        
        threading.Thread(target=segment_thread, daemon=True).start()
    
    def on_interactive_segment_completed(self: 'MainWindow', result):
        """交互式分割完成回调"""
        self.progress.stop()
        self.progress.pack_forget()
        
        if result is None:
            self.update_status("分割失败")
            return
        
        self.current_result = result
        
        # 获取处理后的mask（应用平滑如果开关打开）
        processed_mask = self._get_processed_mask(result.mask)
        
        # 可视化结果
        result_image = self.image_processor.visualize_mask(self.image, processed_mask)
        self.current_result_image = result_image  # 保存结果图片用于窗口调整
        self.display_image(result_image, self.result_canvas)
        
        # 状态提示
        smooth_status = " (已平滑)" if self.smooth_mask_var.get() else ""
        channel_status = " | 通道模式：裁剪将使用原图" if self._is_using_channel_mode() else ""
        self.update_status(f"分割完成{smooth_status}，得分: {result.score:.3f}{channel_status}")
        
        # 保存到历史记录（支持撤销）
        self._save_history_state()
    
    def clear_selection(self: 'MainWindow'):
        """清除选择"""
        self.selected_points = []
        self.selected_labels = []
        self.selected_box = None
        self.current_result = None
        self.all_results = None
        self.current_result_image = None  # 清除结果图片
        
        self.original_canvas.delete("selection")
        self.original_canvas.delete("tempbox")
        self.result_canvas.delete("all")
        
        # 清空历史记录
        self.history_stack = []
        self.history_index = -1
        self._update_history_buttons()
        
        self.update_status("已清除选择")
    
    def export_selected(self: 'MainWindow'):
        """导出选中对象"""
        if self.current_result is None:
            messagebox.showwarning(
                "警告", 
                "请先选择对象！\n\n使用单点或框选模式选择对象。",
                parent=self.root
            )
            return
        
        # 选择保存路径
        default_dir = FileUtils.get_desktop_path()
        default_name = "selected.png"
        if self.image_path:
            default_name = Path(self.image_path).stem + "_selected.png"
        
        save_path = filedialog.asksaveasfilename(
            title="保存选中对象",
            initialdir=default_dir,
            initialfile=default_name,
            defaultextension=".png",
            filetypes=[("PNG 图片", "*.png"), ("所有文件", "*.*")]
        )
        
        if not save_path:
            return
        
        # 获取处理后的mask（应用平滑如果开关打开）
        processed_mask = self._get_processed_mask(self.current_result.mask)
        
        # 保存图片（使用原始图像进行裁剪）
        success = self.image_processor.save_masked_image(
            self._get_image_for_clip(),
            processed_mask,
            save_path
        )
        
        if success:
            smooth_info = " (已平滑)" if self.smooth_mask_var.get() else ""
            self.update_status(f"已保存{smooth_info}: {Path(save_path).name}")
            messagebox.showinfo("成功", f"选中对象已保存到:\n{save_path}{smooth_info}", parent=self.root)
        else:
            messagebox.showerror("错误", "保存失败！", parent=self.root)
    
    def change_mode(self: 'MainWindow'):
        """切换选择模式"""
        self.selection_mode = self.mode_var.get()
        mode_names = {
            "auto": "自动分割",
            "point": "单点选择",
            "box": "框选模式"
        }
        self.update_status(f"当前模式: {mode_names.get(self.selection_mode, '未知')}")
    
    def _on_smooth_toggle(self: 'MainWindow'):
        """平滑开关切换事件"""
        is_smooth = self.smooth_mask_var.get()
        status = "已启用" if is_smooth else "已禁用"
        self.update_status(f"边缘平滑 {status}")
        self.logger.info(f"边缘平滑开关: {status}")
        
        # 如果当前有分割结果，重新显示（应用或取消平滑）
        if self.current_result is not None:
            self._refresh_current_result()
    
    def _check_prerequisites(self: 'MainWindow') -> bool:
        """检查前提条件"""
        if self.image is None:
            messagebox.showwarning("警告", "请先加载图片！", parent=self.root)
            return False
        
        if not self.sam_model.is_loaded():
            messagebox.showwarning("警告", "请先加载 SAM 模型！", parent=self.root)
            return False
        
        return True

